using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace WindowsPhoneGame1.Shapes
{
    public class RectangleF : Shape
    {
        private float width, height;

        public float X { get; set; }
        public float Y { get; set; }
        public float Width
        {
            get { return width; }
            private set
            {
                if (value >= 0)
                    width = value;
                else
                    throw new ArgumentException("Width cannot be negative.");
            }
        }
        public float Height
        {
            get { return height; }
            set
            {
                if (value >= 0)
                    height = value;
                else
                    throw new ArgumentException("Height cannot be negative.");
            }
        }

        public override RectangleF Bounds { get { return bounds; } protected set { bounds = value; } }

        public RectangleF(float x, float y, float width, float height)
        {
            X = x;
            Y = y;
            Width = width;
            Height = height;
            SetBounds();
        }

        public override void SetBounds()
        {
            Bounds = this;
        }

        public ContainmentType Contains(RectangleF other)
        {
            if (other.X + other.Width < X ||
                other.X > X + Width)
                return ContainmentType.Disjoint;

            if (other.Y + other.Height < Y ||
                other.Y > Y + Height)
                return ContainmentType.Disjoint;

            if (other.X - X + other.Width < Width &&
                other.Y - Y + other.Height < Height)
                return ContainmentType.Contains;

            return ContainmentType.Intersects;
        }

        public ContainmentType Contains(PointF other)
        {
            if (other.X < X || other.X > X + Width ||
                other.Y < Y || other.Y > Y + Height)
                // point is outside
                return ContainmentType.Disjoint;

            if (Math.Abs(other.X - X) < MARGIN ||
                Math.Abs(other.X - (X + Width)) < MARGIN)
                // point is on a horizontal line
                return ContainmentType.Intersects;

            if (Math.Abs(other.Y - Y) < MARGIN ||
                Math.Abs(other.Y - (Y + Width)) < MARGIN)
                // point is on a vertical line
                return ContainmentType.Intersects;

            // point is inside
            return ContainmentType.Contains;
        }

        public override ContainmentType contains(Shape shape)
        {
            if (shape is PointF)
                return Contains((PointF)shape);
            if (shape is Line)
                return Contains((RectangleF)shape);
            throw new ArgumentException("Does not support collision with type " + shape.GetType());
        }
    }
}